<template>
  <a-drawer
    title="附件详情"
    :width="isMobile() ? '100%' : '480'"
    closable
    :visible="visible"
    destroyOnClose
    @close="onClose"
  >
    <a-row type="flex" align="middle">
      <a-col :span="24">
        <div class="attach-detail-img">
          <div v-show="nonsupportPreviewVisible">此文件不支持预览</div>
          <a :href="attachment.path" target="_blank">
            <img :src="attachment.path" v-show="photoPreviewVisible" class="w-full" loading="lazy" />
          </a>
          <d-player ref="player" :options="videoOptions" v-show="videoPreviewVisible" class="w-full video-player-box">
          </d-player>
        </div>
      </a-col>
      <a-divider />
      <a-col :span="24">
        <a-list itemLayout="horizontal">
          <a-list-item>
            <a-list-item-meta>
              <template slot="description" v-if="editable">
                <a-input ref="nameInput" v-model="attachment.name" @blur="doUpdateAttachment" />
              </template>
              <template slot="description" v-else>{{ attachment.name }}</template>
              <span slot="title">
                附件名：
                <a href="javascript:void(0);">
                  <a-icon type="edit" @click="handleEditName" />
                </a>
              </span>
            </a-list-item-meta>
          </a-list-item>
          <a-list-item>
            <a-list-item-meta :description="attachment.mediaType">
              <span slot="title">附件类型：</span>
            </a-list-item-meta>
          </a-list-item>
          <a-list-item>
            <a-list-item-meta :description="attachment.typeProperty">
              <span slot="title">存储位置：</span>
            </a-list-item-meta>
          </a-list-item>
          <a-list-item>
            <a-list-item-meta>
              <template slot="description">
                {{ attachment.size | fileSizeFormat }}
              </template>
              <span slot="title">附件大小：</span>
            </a-list-item-meta>
          </a-list-item>
          <a-list-item v-if="photoPreviewVisible">
            <a-list-item-meta :description="attachment.height + 'x' + attachment.width">
              <span slot="title">图片尺寸：</span>
            </a-list-item-meta>
          </a-list-item>
          <a-list-item>
            <a-list-item-meta>
              <template slot="description">
                {{ attachment.createTime | moment }}
              </template>
              <span slot="title">上传日期：</span>
            </a-list-item-meta>
          </a-list-item>
          <a-list-item>
            <a-list-item-meta :description="attachment.path">
              <span slot="title">
                普通链接：
                <a href="javascript:void(0);" @click="handleCopyNormalLink">
                  <a-icon type="copy" />
                </a>
              </span>
            </a-list-item-meta>
          </a-list-item>
          <a-list-item v-if="photoPreviewVisible">
            <a-list-item-meta>
              <span slot="description">![{{ attachment.name }}]({{ attachment.path }})</span>
              <span slot="title">
                Markdown 格式：
                <a href="javascript:void(0);" @click="handleCopyMarkdownLink">
                  <a-icon type="copy" />
                </a>
              </span>
            </a-list-item-meta>
          </a-list-item>
        </a-list>
      </a-col>
    </a-row>
    <a-divider class="divider-transparent" />
    <div class="bottom-control">
      <a-space>
        <a-popconfirm
          title="你确定要添加到图库？"
          @confirm="handleAddToPhoto"
          okText="确定"
          cancelText="取消"
          v-if="addToPhoto"
        >
          <a-button type="dashed">添加到图库</a-button>
        </a-popconfirm>
        <a-popconfirm title="你确定要删除该附件？" @confirm="handleDeleteAttachment" okText="确定" cancelText="取消">
          <ReactiveButton
            type="danger"
            @callback="handleDeletedCallback"
            :loading="deleting"
            :errored="deleteErrored"
            text="删除"
            loadedText="删除成功"
            erroredText="删除失败"
          ></ReactiveButton>
        </a-popconfirm>
      </a-space>
    </div>
  </a-drawer>
</template>

<script>
import { mixin, mixinDevice } from '@/mixins/mixin.js'
import attachmentApi from '@/api/attachment'
import photoApi from '@/api/photo'
import 'vue-dplayer/dist/vue-dplayer.css'
import VueDPlayer from 'vue-dplayer'
import flvjs from 'flv.js'
window.flvjs = flvjs

export default {
  name: 'AttachmentDetailDrawer',
  mixins: [mixin, mixinDevice],
  components: {
    'd-player': VueDPlayer
  },
  data() {
    return {
      editable: false,
      photo: {},
      photoPreviewVisible: false,
      videoPreviewVisible: false,
      nonsupportPreviewVisible: false,
      player: {},
      deleting: false,
      deleteErrored: false,
      videoOptions: {
        lang: 'zh-cn',
        video: {
          url: '',
          type: 'auto'
        }
      }
    }
  },
  model: {
    prop: 'visible',
    event: 'close'
  },
  props: {
    attachment: {
      type: Object,
      required: true
    },
    addToPhoto: {
      type: Boolean,
      required: false,
      default: false
    },
    visible: {
      type: Boolean,
      required: false,
      default: true
    }
  },
  mounted() {
    this.player = this.$refs.player
  },
  watch: {
    attachment(newValue) {
      if (newValue) {
        this.handleJudgeMediaType(newValue)
      }
    }
  },
  methods: {
    handleDeleteAttachment() {
      this.deleting = true
      attachmentApi
        .delete(this.attachment.id)
        .catch(() => {
          this.deleteErrored = true
        })
        .finally(() => {
          setTimeout(() => {
            this.deleting = false
          }, 400)
        })
    },
    handleDeletedCallback() {
      this.$emit('delete', this.attachment)
      this.deleteErrored = false
      this.onClose()
    },
    handleEditName() {
      this.editable = !this.editable
      if (this.editable) {
        this.$nextTick(() => {
          this.$refs.nameInput.focus()
        })
      }
    },
    doUpdateAttachment() {
      if (!this.attachment.name) {
        this.$notification['error']({
          message: '提示',
          description: '附件名称不能为空！'
        })
        return
      }
      attachmentApi.update(this.attachment.id, this.attachment).then(response => {
        this.$log.debug('Updated attachment', response.data.data)
      })
      this.editable = false
    },
    handleCopyNormalLink() {
      const text = `${encodeURI(this.attachment.path)}`
      this.$copyText(text)
        .then(message => {
          this.$log.debug('copy', message)
          this.$message.success('复制成功！')
        })
        .catch(err => {
          this.$log.debug('copy.err', err)
          this.$message.error('复制失败！')
        })
    },
    handleCopyMarkdownLink() {
      const text = `![${this.attachment.name}](${encodeURI(this.attachment.path)})`
      this.$copyText(text)
        .then(message => {
          this.$log.debug('copy', message)
          this.$message.success('复制成功！')
        })
        .catch(err => {
          this.$log.debug('copy.err', err)
          this.$message.error('复制失败！')
        })
    },
    handleAddToPhoto() {
      this.photo['name'] = this.attachment.name
      this.photo['thumbnail'] = encodeURI(this.attachment.thumbPath)
      this.photo['url'] = encodeURI(this.attachment.path)
      this.photo['takeTime'] = new Date().getTime()
      photoApi.create(this.photo).then(() => {
        this.$message.success('添加成功！')
        this.photo = {}
      })
    },
    onClose() {
      this.$emit('close', false)
    },
    handleJudgeMediaType(attachment) {
      const mediaType = attachment.mediaType
      // 判断文件类型
      if (mediaType) {
        const prefix = mediaType.split('/')[0]

        if (prefix === 'video' || prefix === 'flv') {
          // 控制各个组件的显示
          this.handlePreviewVisible(false, true, false)

          // 去除视频地址后面的参数
          const lastIndex = attachment.path.lastIndexOf('?')
          const path = attachment.path.substring(0, lastIndex)

          // 设置视频地址
          this.$set(this.videoOptions.video, 'url', path)
          this.$log.debug('video url', path)
        } else if (prefix === 'image') {
          this.handlePreviewVisible(true, false, false)
        } else {
          this.handlePreviewVisible(false, false, true)
        }
      }
    },
    handlePreviewVisible(photo, video, nonsupport) {
      // 为了更好的使vue监听到组件变化及时刷新,方式修改组件后需要刷新才能显示一下部分
      this.$set(this, 'photoPreviewVisible', photo)
      this.$set(this, 'videoPreviewVisible', video)
      this.$set(this, 'nonsupportPreviewVisible', nonsupport)
    }
  }
}
</script>
